<?php

namespace Common\Service;
class AddonService
{
    public static $checkConfig = ['name', 'title', 'version', 'author',]; // 必须验证的配置项
    protected static $error = '';

    public static function getError()
    {
        return self::$error;
    }

    /**
     * 插件安装
     * @param $name
     * @return bool
     */
    public static function install($name)
    {
        $model = D('Addon');
        $list = self::getLocalAddons();
        $addon = $list[$name];
        if ($addon['installed']) {
            // 禁止重复安装
            self::$error = '插件已经安装';
            return false;
        }
        $path = self::getAddonsPath($name);
        $file = $path . $name . DIRECTORY_SEPARATOR . $name . C('ADDON_BASE_EXT') . EXT;
        if (is_file($file)) {
            $class = 'Addons\\' . $name . '\\' . $name . C('ADDON_BASE_EXT');
            $hand = new $class($addon);
            if (!method_exists($hand, 'install')) {
                self::$error = '请编写安装脚本';
                return false;
            } else if (!method_exists($hand, 'register_hook')) {
                self::$error = '请指定插件Hook';
                return false;
            }
            $res = $hand->install($addon);
            $addon['hook_list'] = serialize($hand->register_hook());
            if ($res) {
                // 安装成功马上向数据库记录相应数据
                $m = array('name' => $name);
                $data = $model->create($addon);
                if ($data) {
                    $res = $model->in2replace($data, $m) !== false ? true : false;
                } else {
                    self::$error = $model->getError();
                    return false;
                }
            }
            return $res;
        }
        self::$error = '插件主文件丢失';
        return false;
    }

    /**
     * 插件卸载
     * 执行逻辑基本与安装操作一致
     * @param $name
     * @return bool
     */
    public static function uninstall($name)
    {
        $list = self::getLocalAddons();
        $addon = $list[$name];
        if (!$addon['installed']) {
            // 禁止重复卸载
            self::$error = '插件已经卸载或未安装';
            return false;
        }
        $path = self::getAddonsPath($name);
        $file = $path . $name . DIRECTORY_SEPARATOR . $name . C('ADDON_BASE_EXT') . EXT;
        if (is_file($file)) {
            $class = 'Addons\\' . $name . '\\' . $name . C('ADDON_BASE_EXT');
            $hand = new $class($addon);
            if (!method_exists($hand, 'uninstall')) {
                self::$error = '请编写卸载脚本';
                return false;
            }
            $res = $hand->uninstall($addon);
            if ($res) {
                // 卸载成功马上从数据库中删除插件的数据
                $model = D('Addon');
                $m = array(
                    'name' => $name
                );
                $res = $model->where($m)->delete();
            }
            return $res;
        }
        self::$erorr = '插件主文件丢失';
        return false;
    }

    /**
     * 插件开关
     * @param $name
     * @param $status 状态代码 1开启 0关闭
     * @return bool
     */
    public static function status($name, $status = 1)
    {
        $list = self::getLocalAddons();
        $addon = $list[$name];
        if (!$addon['installed']) {
            // 未安装的插件不允许开关
            self::$error = '插件已经卸载或未安装';
            return false;
        }
        $path = self::getAddonsPath($name);
        $file = $path . $name . DIRECTORY_SEPARATOR . $name . C('ADDON_BASE_EXT') . EXT;
        if (is_file($file)) {
            $class = 'Addons\\' . $name . '\\' . $name . C('ADDON_BASE_EXT');
            $hand = new $class($addon);
            if (!method_exists($hand, 'start')) {
                self::$error = '请编写卸载脚本';
                return false;
            } else if (!method_exists($hand, 'register_hook')) {
                self::$error = '请指定插件Hook';
                return false;
            }
            $res = $hand->start($status);
            $addon['hook_list'] = serialize($hand->register_hook());
            if ($res) {
                $model = D('Addon');
                $m = array('name' => $name);
                $addon['status'] = $status;
                $data = $model->create($addon);
                if ($data) {
                    $res = $model->where($m)->save($addon);
                } else {
                    self::$error = $model->getError();
                }
            }
            return $res;
        }
        self::$erorr = '插件主文件丢失';
        return false;
    }

    /**
     * 获取本地插件 & 检测已安装的插件
     * @return array
     */
    public static function getLocalAddons()
    {
        $dir = self::getAddonsPath() . DIRECTORY_SEPARATOR; // 插件路径
        $addons = array();
        $model = D('Addon');
        if (is_dir($dir)) {
            // 读插件目录
            foreach (glob($dir . DIRECTORY_SEPARATOR . '*') as $path) {
                if (is_dir($path) && is_file($path . DIRECTORY_SEPARATOR . 'config.php')) {
                    $config = include $path . DIRECTORY_SEPARATOR . 'config.php';// 插件信息配置文件 固定命名
                    $config['installed'] = 0;
                    if (self::checkConfig($config)) {
                        if ($row = $model->findOneAddon($config['name'])) {
                            $config = array_merge($config, $row);
                            $config['installed'] = 1;
                            unset($row);
                        }
                        $addons[$config['name']] = $config; //
                    }
                }
            }
        }
        return $addons;
    }

    /**
     * 验证插件配置是否完整
     * @param $config
     * @return bool
     */
    protected static function checkConfig($config)
    {
        foreach (self::$checkConfig as $v) {
            if (!isset($config[$v]) || $config[$v] == null || $config[$v] == false) {
                return false;
            }
        }
        return true;
    }

    public static function getAddonsPath()
    {
        return C('ADDON_PATH');
    }

    // 组装某个插件的目录
    public static function makePath($name)
    {
        return self::getAddonsPath() . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR;
    }
}